""" S3D Python TOols Launcher"""

import sys
import os
import subprocess
from PyQt4.QtGui import *
from PyQt4.QtCore import SIGNAL
import S3DPath
from S3D import QtHelper, IO

FILE_PATH = os.path.split(__file__)[0]
DEFAULT_ICON_PATH   = FILE_PATH + "\\icons\\default.ico"
TITLE_ICON          = QtHelper.loadIcon("ToolsLauncher")

class _AppInfo:
    def __init__(self, **kw):
        for name, value in kw.items():
            setattr(self, name, value)

class LauncherWindow(QMainWindow):
    def __init__(self):
        super(LauncherWindow, self).__init__()

        self.setWindowTitle(self.tr("Tools Launcher"))
        self.setMinimumSize(640, 400)

        self.isInitializing = True
        self.initUI()
        self.initToolsList()
        self.isInitializing = False

        self.setWindowIcon(TITLE_ICON)

        self.tree.setCurrentItem(self.tree.topLevelItem(0))

        self.show()

    def initUI(self):
        centralWidget = QWidget(self)

        self.setCentralWidget(centralWidget)

        self.tree = tree  = QTreeWidget(centralWidget)
        tree.setMaximumWidth(250)
        tree.setHeaderLabels([self.tr("Categories")])

        self.icons = icons = QListWidget(centralWidget)
        icons.setViewMode(QListView.IconMode)

        layout = QGridLayout(centralWidget)
        layout.addWidget(tree, 0, 0)
        layout.addWidget(icons, 0, 1)

        self.connect(tree,  SIGNAL("currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)"),    self.updateAppList)
        self.connect(icons, SIGNAL("itemDoubleClicked(QListWidgetItem*)"),                      self.onExecuteApp)

    def initToolsList(self):
        self.appList = []

        allItem = self.makeTreeItem("All", None)
        self.tree.addTopLevelItem(allItem)
        allItem.setExpanded(True)

        # collect applications
        for path in IO.walk(FILE_PATH, ".py"):
            prefix, name = os.path.split(path)
            if name.lower() != "__init__.py" or not prefix[2:]:
                continue

            import_path = _convert_path_to_import(path[len(FILE_PATH) + 1:])

            try:
                m = IO.import_from(import_path)
                self.addApplication(import_path, m.APPLICATION_INFO)
            except (ImportError, AttributeError, KeyError):
                #import traceback
                #traceback.print_exc()
                pass

        # update groups
        groups = [p.group for p in self.appList]
        for group in sorted(groups):
            self.addGroup(allItem, group)

    def updateAppList(self):
        if self.isInitializing:
            return

        self.icons.clear()

        group = self.tree.currentItem().group
        for app in sorted(self.appList, key=lambda x: x.name):
            if group is not None and app.group != group:
                continue

            item = QListWidgetItem(QIcon(app.icon), app.name)
            item.app = app
            self.icons.addItem(item)

    def onExecuteApp(self, item):
        try:
            os.chdir(FILE_PATH)
            m = IO.import_from(item.app.main)
            subprocess.Popen([sys.executable, m.__file__])
        except Exception as e:
            QMessageBox.warning(self, self.tr("Failed"), self.tr("Failed to launch application: %1\n\n%2").arg(item.app.name).arg(e.message), QMessageBox.Ok)

    def addApplication(self, import_path, info):
        path_split = import_path.split('.')

        rec         = _AppInfo(
            name    = info.get("name")  or path_split[-2],               # S3D.Tools.SomeToolName.__init__ -> SomeToolName
            group   = info.get("group") or '.'.join(path_split[2:-2]),   # S3D.Tools.Group.SubGroup.SomeToolName.__init__ -> Group.SubGroup
            main    = info.get("main")  or '.'.join(path_split[:-1] + ["__main__"]),    # S3D.Tools.SomeToolName.__init__ -> S3D.Tools.SomeToolName
        )

        try:
            rec.icon = os.path.join(FILE_PATH, info["icon"])
        except KeyError:
            rec.icon = DEFAULT_ICON_PATH

        self.appList.append(rec)

    def addGroup(self, topItem, group):
        for child in _treeItemChilds(topItem):
            if child.name == group:
                return

        item = self.makeTreeItem(group, group)
        topItem.addChild(item)

    def makeTreeItem(self, name, group):
        item = QTreeWidgetItem([self.tr(name)])
        item.name   = name
        item.group  = group
        return item

def _convert_path_to_import(path):
    path = path[:-3] # strip .py
    path = path.replace(os.sep, ".")
    return "S3D.Tools." + path

def _treeItemChilds(item):
    for index in xrange(item.childCount()):
        yield item.child(index)

if __name__ == "__main__":
    QtHelper.ensureSingleApp("S3D Tools Launcher")
    wnd = LauncherWindow()
    sys.exit(QtHelper.qApp.exec_())